package data

import (
	"fmt"
	"sync"
	"yunj/app/enum/redisenum"
	"yunj/app/model"
	"yunj/pkg/global"
	"yunj/pkg/yunj/app/enum/stateenum"
	yunjModel "yunj/pkg/yunj/app/model"
	"yunj/pkg/yunj/core/db"

	"gorm.io/gorm"
)

var dataCategoryMutex sync.RWMutex

type category struct {
	// 所有权限
	defaultCategory *model.Category // 默认分类
}

var Category = &category{}

// 获取默认分类
func (s *category) GetDefaultCategory() *model.Category {
	dataCategoryMutex.RLock()         // 获取读锁
	defer dataCategoryMutex.RUnlock() // 释放读锁
	return s.defaultCategory
}

// 准备默认分类
func (s *category) prepareDefaultCategory() (err error) {
	var category model.Category
	dbErr := global.MySQL.Model(&model.Category{}).Where("`alias` = ?", global.Config.Default.Category.Alias).First(&category).Error
	if dbErr != nil && dbErr != gorm.ErrRecordNotFound {
		err = fmt.Errorf("默认分类数据获取异常！%v", dbErr)
		return
	}
	s.defaultCategory = &category
	return
}

// 数据准备或重置（等于缓存重置）
func CategoryPrepareOrReset() (err error) {
	dataCategoryMutex.Lock()         // 获取写锁
	defer dataCategoryMutex.Unlock() // 释放写锁
	// 清理redis缓存
	if err = redisenum.GroupByValue(redisenum.CATEGORY_CHANGE).DelCache(); err != nil {
		err = fmt.Errorf("分类Redis缓存清理异常！%v", err)
		return err
	}
	// 准备默认分类
	if err := Category.prepareDefaultCategory(); err != nil {
		return err
	}
	return
}

// 处理所有分类数据的完整属性值（补充完整名称等），并清理缓存
func HandleAllCategoryFullAttr() (err error) {
	var items []*model.Category
	if err = global.MySQL.Where("state <> ?", stateenum.DELETED).Select("id", "pid").Find(&items).Error; err != nil {
		err = fmt.Errorf("处理所有分类数据的完整属性值：数据获取异常！%v", err)
		return
	}
	if len(items) > 0 {
		// 获取所有要修改数据
		handleCategoryFullAttr(items, map[uint64]*model.Category{0: nil})
		dbItems := make([]map[string]interface{}, 0, len(items))
		for _, item := range items {
			dbPids, dbValueErr := item.Pids.Value()
			if dbValueErr != nil {
				err = fmt.Errorf("处理所有分类数据的完整属性值：获取pids异常！%v", dbValueErr)
				return
			}
			dbItems = append(dbItems, map[string]interface{}{
				"id":    item.Id,
				"pids":  dbPids,
				"level": item.Level,
			})
		}
		// 批量修改数据
		res := db.Model(&model.Category{}).BatchChange(dbItems)
		if res.Error != nil {
			err = fmt.Errorf("处理所有分类数据的完整属性值：批量修改数据失败！%v", res.Error)
			return
		}
	}
	// 清理缓存
	err = CategoryPrepareOrReset()
	if err != nil {
		err = fmt.Errorf("处理所有分类数据的完整属性值：清理缓存失败！%v", err)
	}
	return
}

func handleCategoryFullAttr(items []*model.Category, parentsMap map[uint64]*model.Category) (err error) {
	newParentsMap := map[uint64]*model.Category{}
	for _, item := range items {
		parent, exists := parentsMap[item.Pid]
		if !exists {
			continue
		}
		pids := yunjModel.Uint64SliceJson{}
		if parent != nil {
			pids = append(parent.Pids, parent.Id)
		}
		var level int
		if parent != nil {
			level = parent.Level + 1
		} else {
			level = 0
		}
		item.Pids = pids
		item.Level = level
		newParentsMap[item.Id] = item
	}
	if len(newParentsMap) > 0 {
		return handleCategoryFullAttr(items, newParentsMap)
	}
	return
}
